package org.etherframework.tests.features.event
{
	import org.etherframework.core.EtherConfig;
	import org.etherframework.tests.features.event.configs.GlobalConfig;
	import org.etherframework.tests.features.event.configs.HierarchicalConfig;
	import org.etherframework.tests.features.event.configs.LocalConfig;
	import org.etherframework.tests.features.event.events.NormalEvent;
	import org.etherframework.tests.utils.ModuleHierarchy;
	import org.etherframework.tests.utils.TestUtility;
	import org.fluint.uiImpersonation.UIImpersonator;
	import org.hamcrest.assertThat;
	import org.hamcrest.collection.array;
	import org.hamcrest.collection.arrayWithSize;
	import org.hamcrest.object.equalTo;

	public class when_using_events
	{	
		private static var _testUtility:TestUtility = new TestUtility();
		private static var _hiearchy:ModuleHierarchy;
		
		[BeforeClass]
		public static function setUpBeforeClass():void
		{
			const configs:Vector.<EtherConfig> = new Vector.<EtherConfig>();
			configs.push(new HierarchicalConfig(), new HierarchicalConfig(), 
				new HierarchicalConfig(), new GlobalConfig(), new LocalConfig()); 
			_hiearchy = _testUtility.createHierarchy(configs);
			UIImpersonator.addChild(_hiearchy.module.view);
		}
		
		[AfterClass]
		public static function tearDownAfterClass():void
		{
			UIImpersonator.removeAllChildren();
			_testUtility.dispose();
		}
		
		[Test(order=1)]
		public function it_should_be_handled_when_dispatched_in_hierarchy():void
		{
			// Arrange
			var triggers:Array = [];
			var handler1:Function = function(event:NormalEvent):void {triggers.push(handler1);};
			var handler2:Function = function(event:NormalEvent):void {triggers.push(handler2);};
			var handler3:Function = function(event:NormalEvent):void {triggers.push(handler3);};
			var handler4:Function = function(event:NormalEvent):void {triggers.push(handler4);};
			var handler5:Function = function(event:NormalEvent):void {triggers.push(handler5);};
			
			_hiearchy.module.ether.listen(NormalEvent.SOME, handler1);
			_hiearchy.next().module.ether.listen(NormalEvent.SOME, handler2);
			_hiearchy.next().next().module.ether.listen(NormalEvent.SOME, handler3);
			_hiearchy.next().next().next().module.ether.listen(NormalEvent.SOME, handler4);
			_hiearchy.next().next().next().next().module.ether.listen(NormalEvent.SOME, handler5);
			
			// Act
			_hiearchy.module.ether.dispatch(new NormalEvent(NormalEvent.SOME));
			
			// Assert
			assertThat(triggers, arrayWithSize(4));
			assertThat(triggers, array(equalTo(handler1), equalTo(handler2), equalTo(handler3), equalTo(handler4)));
		}
		
		[Test(order=2)]
		public function it_should_be_handled_when_dispatched_in_local():void
		{
			// Arrange
			var triggers:Array = [];
			var handler1:Function = function(event:NormalEvent):void {triggers.push(handler1);};
			var handler2:Function = function(event:NormalEvent):void {triggers.push(handler2);};
			var handler3:Function = function(event:NormalEvent):void {triggers.push(handler3);};
			var handler4:Function = function(event:NormalEvent):void {triggers.push(handler4);};
			var handler5:Function = function(event:NormalEvent):void {triggers.push(handler5);};
			
			_hiearchy.module.ether.listen(NormalEvent.SOME, handler1);
			_hiearchy.next().module.ether.listen(NormalEvent.SOME, handler2);
			_hiearchy.next().next().module.ether.listen(NormalEvent.SOME, handler3);
			_hiearchy.next().next().next().module.ether.listen(NormalEvent.SOME, handler4);
			_hiearchy.next().next().next().next().module.ether.listen(NormalEvent.SOME, handler5);
			
			// Act
			_hiearchy.next().next().next().next().module.ether.dispatch(new NormalEvent(NormalEvent.SOME));
			
			// Assert
			assertThat(triggers, arrayWithSize(1));
			assertThat(triggers, array(equalTo(handler5)));
		}
		
		[Test(order=3)]
		public function it_should_be_handled_when_dispatched_in_global():void
		{
			// Arrange
			var triggers:Array = [];
			var handler1:Function = function(event:NormalEvent):void {triggers.push(handler1);};
			var handler2:Function = function(event:NormalEvent):void {triggers.push(handler2);};
			var handler3:Function = function(event:NormalEvent):void {triggers.push(handler3);};
			var handler4:Function = function(event:NormalEvent):void {triggers.push(handler4);};
			var handler5:Function = function(event:NormalEvent):void {triggers.push(handler5);};
			
			_hiearchy.module.ether.listen(NormalEvent.SOME, handler1);
			_hiearchy.next().module.ether.listen(NormalEvent.SOME, handler2);
			_hiearchy.next().next().module.ether.listen(NormalEvent.SOME, handler3);
			_hiearchy.next().next().next().module.ether.listen(NormalEvent.SOME, handler4);
			_hiearchy.next().next().next().next().module.ether.listen(NormalEvent.SOME, handler5);
			
			// Act
			_hiearchy.next().next().next().module.ether.dispatch(new NormalEvent(NormalEvent.SOME));
			
			// Assert
			assertThat(triggers, arrayWithSize(4));
			assertThat(triggers, array(equalTo(handler1), equalTo(handler2), equalTo(handler3), equalTo(handler4)));
		}
	}
}